package china.accountinghelper.activity;

import com.xdroid.base.AsyncTaskBase;
import com.xdroid.util.DateTimeUtil;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import china.wc.tallyhelper.R;
import china.wc.tallyhelper.adapter.AdapterListViewBookList;
import china.wc.tallyhelper.adapter.AdapterListViewCategoryList;
import china.wc.tallyhelper.adapter.AdapterListViewPersonList;
import china.wc.tallyhelper.adapter.AdapterSpinnerAllConsumer;
import china.wc.tallyhelper.adapter.AdapterSpinnerEnabledConsumer;
import china.wc.tallyhelper.business.BusinessExpense;
import china.wc.tallyhelper.business.BusinessExpenseDetail;
import china.wc.tallyhelper.controls.SlideMenu;
import china.wc.tallyhelper.controls.SlideMenuItem;
import china.wc.tallyhelper.model.ModelExpense;
import china.wc.tallyhelper.model.ModelExpenseDetail;
import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ScrollView;
import android.widget.Spinner;
import android.widget.TableLayout;
import android.widget.TextView;

public class ActivityExpenseAddAndEdit extends ActivityFrame implements OnClickListener, DatePickerDialog.OnDateSetListener, OnItemSelectedListener, TextWatcher, android.content.DialogInterface.OnClickListener
{
    static final int        DIALOG_DATEPICKER = 1;
    static final int        DIALOG_EXIT = 2;

    private ModelExpense mHandlingExpense;
    private BusinessExpense mBusinessExpense;
    private BusinessExpenseDetail mBusinessExpenseDetail;
    private AdapterListViewBookList mAdapterListViewBookList;
    private AdapterListViewCategoryList mAdapterListViewCategoryList;
    private AdapterListViewPersonList mAdapterListViewPersonList;

    private ScrollView mActivityExpenseAddAndEdit_ScrollView_ScrollView;
    private ImageButton     mActivityExpenseAddAndEdit_ImageButton_OpenDatePicker;
    private TextView        mActivityExpenseAddAndEdit_TextView_ExpenseDate;
    private Spinner mActivityExpenseAddAndEdit_Spinner_Book;
    private Spinner mActivityExpenseAddAndEdit_Spinner_Category;
    private EditText mActivityExpenseAddAndEdit_EditText_Comment;
    private Spinner mActivityExpenseAddAndEdit_Spinner_Payer;
    private TableLayout mActivityExpenseAddAndEdit_TableLayout_Detail;
    private ImageButton mActivityExpenseAddAndEdit_ImageButton_DetailInsert;
    private Button mActivityExpenseAddAndEdit_Button_Save;
    private Button mActivityExpenseAddAndEdit_Button_SaveAndNew;
    private Button mActivityExpenseAddAndEdit_Button_Cancel;

    private Calendar        mExpenseDate;
    private long            mSelectedBookID;
    private long            mSelectedCategoryID;
    private long            mSelectedPayerID;
    private List<ModelExpenseDetail> mExpenseDetails;

    private List<Spinner> mListConsumers;
    private List<EditText> mListMoneys;
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        // 载入主页面Layout文件
        loadFramebody(R.layout.framebody_expense_add_and_edit);
        // 设置标题
        setTopTitle(R.string.title_expense_add);
        
        executeInitTask(null);
    }

    @Override
    protected Dialog onCreateDialog(int pId, Bundle pArgs)
    {
        Dialog _Dialog = null;

        if (pId == DIALOG_DATEPICKER) {
            _Dialog = new DatePickerDialog(this, this, Calendar.getInstance().get(Calendar.YEAR), Calendar.getInstance().get(Calendar.MONTH), Calendar.getInstance().get(Calendar.DATE));
        } else if (pId == DIALOG_EXIT) {
            AlertDialog.Builder _Builder = new AlertDialog.Builder(this);
            _Builder.setIcon(android.R.drawable.ic_dialog_alert)
                .setTitle(R.string.warning)
                .setMessage(R.string.exit_activity)
                .setPositiveButton(R.string.ok, this)
                .setNegativeButton(R.string.cancel, this);
            _Dialog = _Builder.create();
        }

        return _Dialog;
    }

    @Override
    public void onBackPressed()
    {
        showDialog(DIALOG_EXIT);
    }

    @Override
    protected void initFields()
    {
        mHandlingExpense = (ModelExpense) getIntent().getSerializableExtra(ActivityBookDetail.SELECTED_MODEL_OBJECT);
        mBusinessExpense = new BusinessExpense();
        mBusinessExpenseDetail = new BusinessExpenseDetail();
        
        if (mHandlingExpense==null) {
            mAdapterListViewBookList = new AdapterListViewBookList(this, AdapterListViewBookList.SELECT_ENABLED);
            mAdapterListViewCategoryList = new AdapterListViewCategoryList(this);
            mAdapterListViewPersonList = new AdapterListViewPersonList(this,AdapterListViewPersonList.SELECT_ENABLED);
            mExpenseDate = null;
            mSelectedBookID = -1;
            mSelectedCategoryID = -1;
            mSelectedPayerID = -1;
        } else {
            mAdapterListViewBookList = new AdapterListViewBookList(this, AdapterListViewBookList.SELECT_ALL);
            mAdapterListViewCategoryList = new AdapterListViewCategoryList(this);
            mAdapterListViewPersonList = new AdapterListViewPersonList(this,AdapterListViewPersonList.SELECT_ALL);
            mExpenseDate = mHandlingExpense.getExpenseDate();
            mSelectedBookID = mHandlingExpense.getBookID();
            mSelectedCategoryID = mHandlingExpense.getCategoryID();
            mSelectedPayerID = mHandlingExpense.getPayerID();
        }
        
        mExpenseDetails = new ArrayList<ModelExpenseDetail>();
        mListConsumers = new ArrayList<Spinner>();
        mListMoneys = new ArrayList<EditText>();
    }

    @Override
    protected void initViews()
    {
        mActivityExpenseAddAndEdit_ScrollView_ScrollView = (ScrollView) findViewById(R.id.ActivityExpenseAddAndEdit_ScrollView_ScrollView);
        mActivityExpenseAddAndEdit_ImageButton_OpenDatePicker = (ImageButton) findViewById(R.id.ActivityExpenseAddAndEdit_ImageButton_OpenDatePicker);
        mActivityExpenseAddAndEdit_TextView_ExpenseDate = (TextView) findViewById(R.id.ActivityExpenseAddAndEdit_TextView_ExpenseDate);
        mActivityExpenseAddAndEdit_Spinner_Book = (Spinner) findViewById(R.id.ActivityExpenseAddAndEdit_Spinner_Book);
        mActivityExpenseAddAndEdit_Spinner_Book.setEmptyView(findViewById(R.id.ActivityExpenseAddAndEdit_LinearLayout_NoBook));
        mActivityExpenseAddAndEdit_Spinner_Category = (Spinner) findViewById(R.id.ActivityExpenseAddAndEdit_Spinner_Category);
        mActivityExpenseAddAndEdit_Spinner_Category.setEmptyView(findViewById(R.id.ActivityExpenseAddAndEdit_LinearLayout_NoCategory));
        mActivityExpenseAddAndEdit_EditText_Comment = (EditText) findViewById(R.id.ActivityExpenseAddAndEdit_EditText_Comment);
        mActivityExpenseAddAndEdit_Spinner_Payer = (Spinner) findViewById(R.id.ActivityExpenseAddAndEdit_Spinner_Payer);
        mActivityExpenseAddAndEdit_TableLayout_Detail = (TableLayout) findViewById(R.id.ActivityExpenseAddAndEdit_TableLayout_Detail);
        mActivityExpenseAddAndEdit_ImageButton_DetailInsert = (ImageButton) findViewById(R.id.ActivityExpenseAddAndEdit_ImageButton_DetailInsert);
        mActivityExpenseAddAndEdit_Button_Save = (Button) findViewById(R.id.ActivityExpenseAddAndEdit_Button_Save);
        mActivityExpenseAddAndEdit_Button_SaveAndNew = (Button) findViewById(R.id.ActivityExpenseAddAndEdit_Button_SaveAndNew);
        mActivityExpenseAddAndEdit_Button_Cancel = (Button) findViewById(R.id.ActivityExpenseAddAndEdit_Button_Cancel);
        
        if (mHandlingExpense==null) {
            setExpenseDate(Calendar.getInstance());
            insertNewExpenseDetail(null);
        }else {
            setExpenseDate(mHandlingExpense.getExpenseDate());
            mActivityExpenseAddAndEdit_EditText_Comment.setText(mHandlingExpense.getComment());
            List<ModelExpenseDetail> _ExpenseDetails = mBusinessExpenseDetail.select(mHandlingExpense);
            for (ModelExpenseDetail _TemExpenseDetail : _ExpenseDetails) {
                insertNewExpenseDetail(_TemExpenseDetail);
            }
        }
    }

    @Override
    protected void bindData()
    {
        mActivityExpenseAddAndEdit_Spinner_Book.setAdapter(mAdapterListViewBookList);
        mActivityExpenseAddAndEdit_Spinner_Category.setAdapter(mAdapterListViewCategoryList);
        mActivityExpenseAddAndEdit_Spinner_Payer.setAdapter(mAdapterListViewPersonList);
        
        if (mHandlingExpense==null) {
            
        } else {
            for (int i = 0; i < mAdapterListViewBookList.getCount(); i++) {
                if (mAdapterListViewBookList.getItemId(i)==mHandlingExpense.getBookID()) {
                    mActivityExpenseAddAndEdit_Spinner_Book.setSelection(i, true);
                    break;
                }
            }
            for (int i = 0; i < mAdapterListViewCategoryList.getCount(); i++) {
                if (mAdapterListViewCategoryList.getItemId(i)==mHandlingExpense.getCategoryID()) {
                    mActivityExpenseAddAndEdit_Spinner_Category.setSelection(i, true);
                    break;
                }
            }
            for (int i = 0; i < mAdapterListViewPersonList.getCount(); i++) {
                if (mAdapterListViewPersonList.getItemId(i)==mHandlingExpense.getPayerID()) {
                    mActivityExpenseAddAndEdit_Spinner_Payer.setSelection(i, true);
                    break;
                }
            }
        }
    }

    @Override
    protected void initListeners()
    {
        mActivityExpenseAddAndEdit_ImageButton_OpenDatePicker.setOnClickListener(this);
        mActivityExpenseAddAndEdit_TextView_ExpenseDate.setOnClickListener(this);
        mActivityExpenseAddAndEdit_Spinner_Book.setOnItemSelectedListener(this);
        mActivityExpenseAddAndEdit_Spinner_Category.setOnItemSelectedListener(this);
        mActivityExpenseAddAndEdit_Spinner_Payer.setOnItemSelectedListener(this);
        mActivityExpenseAddAndEdit_ImageButton_DetailInsert.setOnClickListener(this);
        mActivityExpenseAddAndEdit_Button_Save.setOnClickListener(this);
        mActivityExpenseAddAndEdit_Button_SaveAndNew.setOnClickListener(this);
        mActivityExpenseAddAndEdit_Button_Cancel.setOnClickListener(this);
    }

    @Override
    protected void register()
    {
    }
    
    @Override
    protected Object doInBackground(Object... params)
    {
        initFields();
        return null;
    }

    @Override
    protected void onPostExecute(Object result)
    {
        super.onPostExecute(result);
        initViews();
        initListeners();
        bindData();
        register();
    }

    @Override
    public void onClick(View v)
    {
        // 选择消费日期
        if (v.equals(mActivityExpenseAddAndEdit_ImageButton_OpenDatePicker)||v.equals(mActivityExpenseAddAndEdit_TextView_ExpenseDate)) {
            showDialog(DIALOG_DATEPICKER);
            
        // 新增消费记录
        } else if (v.equals(mActivityExpenseAddAndEdit_ImageButton_DetailInsert)) {
            insertNewExpenseDetail(null);
            mActivityExpenseAddAndEdit_ScrollView_ScrollView.post(new Runnable()
            {
                @Override
                public void run()
                {
                    mActivityExpenseAddAndEdit_ScrollView_ScrollView.fullScroll(View.FOCUS_DOWN);
                }
            });
        
        // 保存
        } else if (v.equals(mActivityExpenseAddAndEdit_Button_Save)) {
            if (saveOrUpdate()) {
                finish();
            }
        // 保存并添加新消费纪录
        } else if (v.equals(mActivityExpenseAddAndEdit_Button_SaveAndNew)) {
            if (saveOrUpdate()) {
                finish();
                openActivity(ActivityExpenseAddAndEdit.class);
            }
        // 取消
        } else if (v.equals(mActivityExpenseAddAndEdit_Button_Cancel)) {
            showDialog(DIALOG_EXIT);
        }
        
        
    }

    /**
     * DatePickerDialog的回调方法
     */
    @Override
    public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth)
    {
        setExpenseDate(year, monthOfYear, dayOfMonth);
    }

    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
    {
        if (parent == mActivityExpenseAddAndEdit_Spinner_Book) {
            mSelectedBookID = id;
        } else if (parent == mActivityExpenseAddAndEdit_Spinner_Category) {
            mSelectedCategoryID = id;
        } else if (parent == mActivityExpenseAddAndEdit_Spinner_Payer) {
            mSelectedPayerID = id;
        }
    }

    @Override
    public void onNothingSelected(AdapterView<?> parent)
    {
        mSelectedBookID =-1;
        mSelectedCategoryID = -1;
        mSelectedPayerID = -1;
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after)
    {
    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count)
    {
    }

    /**
     * 校验EditText中输入的小数，小数点后2位的数字都删除。
     * 
     * @param s 待校验的文本
     */
    @Override
    public void afterTextChanged(Editable s)
    {
            String temp = s.toString();
            int posDot = temp.indexOf(".");
            if (posDot <= 0) return;
            if (temp.length() - posDot - 1 > 2)
            {
                s.delete(posDot + 3, posDot + 4);
            }
    }

    @Override
    public void onClick(DialogInterface dialog, int which)
    {
        //退出确认对话框
        if (getShowingDialogID() == DIALOG_EXIT) {
            if (which == DialogInterface.BUTTON_POSITIVE) {
                finish();
            } else if (which ==DialogInterface.BUTTON_NEGATIVE) {
                dialog.dismiss();
            }
        }
    }

    @Override
    public void onSlideMenuItemClick(SlideMenu pSlideMenu, SlideMenuItem pSlideMenuItem, AdapterView<?> pParent, View pView, int pPosition, long pId)
    {
    }

    /**
     * 设置界面上的日期显示框，并给mExpenseDate赋值。
     * 
     * @param pExpenseDate
     */
    private void setExpenseDate(Calendar pExpenseDate)
    {
        mActivityExpenseAddAndEdit_TextView_ExpenseDate.setText(DateTimeUtil.getYearMonthDate2(pExpenseDate));
        mExpenseDate = pExpenseDate;
    }

    /**
     * 设置界面上的日期显示框，并给mExpenseDate赋值。
     * 
     * @param pYear
     *            年
     * @param pMonthOfYear
     *            月，从0开始。
     * @param pDayOfMonth
     *            日
     */
    private void setExpenseDate(int pYear, int pMonthOfYear, int pDayOfMonth)
    {
        Calendar _Calendar = Calendar.getInstance();
        _Calendar.set(Calendar.YEAR, pYear);
        _Calendar.set(Calendar.MONTH, pMonthOfYear);
        _Calendar.set(Calendar.DAY_OF_MONTH, pDayOfMonth);

        setExpenseDate(_Calendar);
    }

    /**
     * 在界面上新增一条消费明细。
     * 
     */
    private void insertNewExpenseDetail(ModelExpenseDetail pExpenseDetails)
    {
        final View _TableRow = inflateView(R.layout.tablerow_expense_detail, null);
        // 选择消费人下拉框
        final Spinner _TableRowExpenseDetail_Spinner_Consumer = (Spinner) _TableRow.findViewById(R.id.TableRowExpenseDetail_Spinner_Consumer);
        mListConsumers.add(_TableRowExpenseDetail_Spinner_Consumer);
        // 消费金额输入框
        final EditText _TableRowExpenseDetail_EditText_Money = (EditText) _TableRow.findViewById(R.id.TableRowExpenseDetail_EditText_Money); 
        mListMoneys.add(_TableRowExpenseDetail_EditText_Money);
        // 删除消费明细按钮
        ImageButton _TableRowExpenseDetail_ImageButton_DetailDelete = (ImageButton) _TableRow.findViewById(R.id.TableRowExpenseDetail_ImageButton_DetailDelete);
        _TableRowExpenseDetail_ImageButton_DetailDelete.setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                mListConsumers.remove(_TableRowExpenseDetail_Spinner_Consumer);
                mListMoneys.remove(_TableRowExpenseDetail_EditText_Money);
                mActivityExpenseAddAndEdit_TableLayout_Detail.removeView(_TableRow);
            }
        });
        
        if (pExpenseDetails == null) {
            AdapterSpinnerEnabledConsumer _AdapterSpinnerEnabledConsumer = new AdapterSpinnerEnabledConsumer(this);
            _TableRowExpenseDetail_Spinner_Consumer.setAdapter(_AdapterSpinnerEnabledConsumer);
            
            _TableRowExpenseDetail_EditText_Money.addTextChangedListener(this);
            
        } else {
            AdapterSpinnerAllConsumer _AdapterSpinnerAllConsumer = new AdapterSpinnerAllConsumer(this);
            _TableRowExpenseDetail_Spinner_Consumer.setAdapter(_AdapterSpinnerAllConsumer);
            for (int i = 0; i < _AdapterSpinnerAllConsumer.getCount(); i++) {
                if (pExpenseDetails.getConsumerID()==_AdapterSpinnerAllConsumer.getItemId(i)) {
                    _TableRowExpenseDetail_Spinner_Consumer.setSelection(i, true);
                }
            }
            
            _TableRowExpenseDetail_EditText_Money.setText(pExpenseDetails.getMoney2()+"");
            _TableRowExpenseDetail_EditText_Money.addTextChangedListener(this);
            
        }
        
        mActivityExpenseAddAndEdit_TableLayout_Detail.addView(_TableRow);
    }
    
    /**
     * 验证当前界面的数据是否满足保存条件
     * 若不满足条件，用Toast提示。
     * 
     * @return
     */
    private boolean isSavable()
    {
        if (mExpenseDate==null) {
            showToastShort(R.string.no_expense_date);
            return false;
        }
        
        if (mSelectedBookID<=0) {
            showToastShort(R.string.no_book);
            mActivityExpenseAddAndEdit_Spinner_Book.requestFocus();
            return false;
        }
        
        if (mSelectedCategoryID<=0) {
            showToastShort(R.string.no_category);
            mActivityExpenseAddAndEdit_Spinner_Category.requestFocus();
            return false;
        }
        
        if (mSelectedPayerID<=0) {
            showToastShort(R.string.no_payer);
            mActivityExpenseAddAndEdit_Spinner_Payer.requestFocus();
            return false;
        }
        
        if (mListConsumers.size()<=0 || mListMoneys.size()<=0) {
            showToastShort(R.string.no_expense_detail);
            mActivityExpenseAddAndEdit_ImageButton_DetailInsert.requestFocus();
            return false;
        }
        
        if (mListConsumers.size()!=mListMoneys.size()) {
            showToastShort("消费人和金额数量不相等");
            return false;
        }
        
        for (int tem = 0; tem < mListConsumers.size(); tem++) {
            Spinner _Spinner = mListConsumers.get(tem);
            EditText _EditText = mListMoneys.get(tem);
            
            long _ConsumerID = _Spinner.getSelectedItemId();
            if (_ConsumerID<=0) {
                _Spinner.requestFocus();
                showToastShort("消费人ID小于等于0");
                return false;
            }
            
            int _Money;
            try {
                _Money =(int) (Double.parseDouble(_EditText.getText().toString()) * 100);
            } catch (NumberFormatException e) {
                showToastShort(R.string.wrong_money);
                _EditText.requestFocus();
                return false;
            }
            if (_Money==0) {
                showToastShort(R.string.no_money);
                _EditText.requestFocus();
                return false;
            }
            
            mExpenseDetails.add(new ModelExpenseDetail(_ConsumerID, _Money));
        }
        
        return true;
    }
    
    /**
     * 保存当前界面的数据。
     * 
     * @return 保存是否成功
     */
    private boolean saveOrUpdate()
    {
        if (isSavable()) {
            
            if (mHandlingExpense == null) {
                ModelExpense _Expense = new ModelExpense();
                _Expense.setExpenseDate(mExpenseDate);
                _Expense.setBookID(mSelectedBookID);
                _Expense.setCategoryID(mSelectedCategoryID);
                _Expense.setCreateTime(Calendar.getInstance());
                _Expense.setComment(mActivityExpenseAddAndEdit_EditText_Comment.getText().toString());
                _Expense.setPayerID(mSelectedPayerID);
                return mBusinessExpense.insertOrUpdateModel(_Expense, mExpenseDetails);
            } else {
                mHandlingExpense.setExpenseDate(mExpenseDate);
                mHandlingExpense.setBookID(mSelectedBookID);
                mHandlingExpense.setCategoryID(mSelectedCategoryID);
                mHandlingExpense.setComment(mActivityExpenseAddAndEdit_EditText_Comment.getText().toString());
                mHandlingExpense.setPayerID(mSelectedPayerID);
                
                return mBusinessExpense.insertOrUpdateModel(mHandlingExpense, mExpenseDetails);
            }
            
        } else {
            return false;
        }
    }
    
}
